<template>
  <div
      :class="{ 'fullscreen-mode': isFullscreen }"
      class="image-viewer"
  >
    <!-- 控制栏 -->
    <div v-if="showControls" class="controls">
      <button :disabled="scale <= minScale" title="缩小" @click="zoomOut">
        <svg height="20" viewBox="0 0 24 24" width="20">
          <path d="M19 13H5v-2h14v2z" fill="currentColor"/>
        </svg>
      </button>

      <span class="scale-display">{{ Math.round(scale * 100) }}%</span>

      <button :disabled="scale >= maxScale" title="放大" @click="zoomIn">
        <svg height="20" viewBox="0 0 24 24" width="20">
          <path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" fill="currentColor"/>
        </svg>
      </button>

      <button title="重置缩放" @click="resetZoom">
        <svg height="20" viewBox="0 0 24 24" width="20">
          <path d="M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z"
                fill="currentColor"/>
        </svg>
      </button>

      <button title="旋转" @click="rotateImage">
        <svg height="20" viewBox="0 0 24 24" width="20">
          <path d="M12 6v3l4-4-4-4v3c-4.42 0-8 3.58-8 8 0 1.57.46 3.03 1.24 4.26L6.7 14.8c-.45-.83-.7-1.79-.7-2.8 0-3.31 2.69-6 6-6zm6.76 1.74L17.3 9.2c.44.84.7 1.79.7 2.8 0 3.31-2.69 6-6 6v-3l-4 4 4 4v-3c4.42 0 8-3.58 8-8 0-1.57-.46-3.03-1.24-4.26z"
                fill="currentColor"/>
        </svg>
      </button>

      <button title="全屏" @click="toggleFullscreen">
        <svg height="20" viewBox="0 0 24 24" width="20">
          <path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z" fill="currentColor"/>
        </svg>
      </button>

      <button title="关闭" @click="closeViewer">
        <svg height="20" viewBox="0 0 24 24" width="20">
          <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
                fill="currentColor"/>
        </svg>
      </button>
    </div>

    <!-- 图片容器 -->
    <div
        :style="containerStyle"
        class="image-container"
    >
      <img
          ref="imageRef"
          :src="imageUrl"
          :style="imageStyle"
          alt="预览图片"
          draggable="false"
          @error="handleImageError"
          @load="handleImageLoad"
      />
    </div>

    <!-- 加载状态 -->
    <div v-if="isLoading" class="loading">
      <div class="spinner"></div>
      <p>加载中...</p>
    </div>

    <!-- 错误状态 -->
    <div v-if="showError" class="error">
      <p>图片加载失败</p>
      <button class="error-button" @click="closeViewer">关闭</button>
    </div>

    <!-- 缩略图导航 -->
    <div v-if="showThumbnails && imageList.length > 1" class="thumbnails">
      <div
          v-for="(img, index) in imageList"
          :key="index"
          :class="['thumbnail', { active: currentImageIndex === index }]"
          @click="switchImage(index)"
      >
        <img :src="img" alt="缩略图"/>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import {ref, computed, onMounted, onUnmounted, watch} from 'vue'
import {useRoute, useRouter} from 'vue-router'


const route = useRoute()
const router = useRouter()

// 响应式数据
const imageUrl = ref('')
const imageList = ref<string[]>([])
const currentImageIndex = ref(0)
const scale = ref(1)
const rotation = ref(0)
const position = ref({x: 0, y: 0})
const isDragging = ref(false)
const isLoading = ref(false)
const showError = ref(false)
const isFullscreen = ref(false)
const imageRef = ref<HTMLImageElement | null>(null)
const imageNaturalSize = ref({width: 0, height: 0})

// 常量配置
const minScale = 0.1
const maxScale = 10
const scaleStep = 0.25

// 计算属性
const showControls = computed(() => !isLoading.value && !showError.value)
const showThumbnails = computed(() => imageList.value.length > 1 && !isLoading.value && !showError.value)

const imageStyle = computed(() => ({
  transform: `scale(${scale.value}) rotate(${rotation.value}deg)`,
  transformOrigin: 'center center',
  cursor: isDragging.value ? 'grabbing' : scale.value > 1 ? 'grab' : 'default'
}))

const containerStyle = computed(() => ({
  transform: `translate(${position.value.x}px, ${position.value.y}px)`
}))

// 方法
const getImageUrlFromQuery = (): void => {
  const urlFromQuery = route.query.imageUrl as string

  if (urlFromQuery) {
    imageList.value = [urlFromQuery]
    imageUrl.value = urlFromQuery
  } else {
    showError.value = true
  }
}

const loadImage = (): void => {
  if (!imageUrl.value) return

  isLoading.value = true
  showError.value = false

  const img = new Image()
  img.onload = () => {
    isLoading.value = false
    resetView()
  }
  img.onerror = () => {
    isLoading.value = false
    showError.value = true
  }
  img.src = imageUrl.value
}

const resetView = (): void => {
  scale.value = 1
  rotation.value = 0
  position.value = {x: 0, y: 0}
}

const zoomIn = (): void => {
  if (scale.value < maxScale) {
    scale.value = Math.min(maxScale, scale.value + scaleStep)
  }
}

const zoomOut = (): void => {
  if (scale.value > minScale) {
    scale.value = Math.max(minScale, scale.value - scaleStep)
  }
}

const resetZoom = (): void => {
  resetView()
}

const rotateImage = (): void => {
  rotation.value = (rotation.value + 90) % 360
}

const toggleFullscreen = (): void => {
  if (!document.fullscreenElement) {
    document.documentElement.requestFullscreen().catch(console.error)
    isFullscreen.value = true
  } else {
    document.exitFullscreen().catch(console.error)
    isFullscreen.value = false
  }
}

const closeViewer = (): void => {
  if (document.fullscreenElement) {
    document.exitFullscreen().catch(console.error)
  }
  router.back()
}

const handleImageLoad = (): void => {
  if (imageRef.value) {
    imageNaturalSize.value = {
      width: imageRef.value.naturalWidth,
      height: imageRef.value.naturalHeight
    }
  }
  isLoading.value = false
}

const handleImageError = (): void => {
  isLoading.value = false
  showError.value = true
}

const switchImage = (index: number): void => {
  if (index >= 0 && index < imageList.value.length) {
    currentImageIndex.value = index
    imageUrl.value = imageList.value[index]
    resetView()
    loadImage()
  }
}

const handleFullscreenChange = (): void => {
  isFullscreen.value = !!document.fullscreenElement
}

// 生命周期
onMounted(() => {
  getImageUrlFromQuery()
  loadImage()

  document.addEventListener('fullscreenchange', handleFullscreenChange)
})

onUnmounted(() => {
  document.removeEventListener('fullscreenchange', handleFullscreenChange)
})

// 监听路由参数变化
watch(() => route.query, () => {
  getImageUrlFromQuery()
  loadImage()
})
</script>

<style scoped>
.image-viewer {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background-color: rgba(0, 0, 0, 0.9);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
  cursor: default;
}

.fullscreen-mode {
  background-color: #000;
}

.controls {
  position: absolute;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 12px;
  padding: 12px;
  background: rgba(0, 0, 0, 0.7);
  border-radius: 8px;
  backdrop-filter: blur(10px);
  z-index: 1001;
}

.controls button {
  background: rgba(255, 255, 255, 0.1);
  border: none;
  border-radius: 4px;
  padding: 8px;
  cursor: pointer;
  color: white;
  transition: background-color 0.2s;
}

.controls button:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.2);
}

.controls button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.scale-display {
  color: white;
  font-size: 14px;
  display: flex;
  align-items: center;
  padding: 0 8px;
}

.image-container {
  position: relative;
  transition: transform 0.1s ease-out;
  max-width: 90vw;
  max-height: 90vh;
}

.image-container img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  user-select: none;
  -webkit-user-drag: none;
}

.loading {
  color: white;
  text-align: center;
}

.spinner {
  width: 40px;
  height: 40px;
  border: 4px solid rgba(255, 255, 255, 0.3);
  border-top: 4px solid white;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin: 0 auto 16px;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.error {
  color: white;
  text-align: center;
}

.error-button {
  margin-top: 16px;
  padding: 8px 16px;
  background: #ff4757;
  border: none;
  border-radius: 4px;
  color: white;
  cursor: pointer;
}

.thumbnails {
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 8px;
  padding: 12px;
  background: rgba(0, 0, 0, 0.7);
  border-radius: 8px;
  backdrop-filter: blur(10px);
}

.thumbnail {
  width: 60px;
  height: 60px;
  border: 2px solid transparent;
  border-radius: 4px;
  overflow: hidden;
  cursor: pointer;
  transition: border-color 0.2s;
}

.thumbnail.active {
  border-color: #007bff;
}

.thumbnail img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .controls {
    top: 10px;
    gap: 8px;
    padding: 8px;
  }

  .controls button {
    padding: 6px;
  }

  .thumbnails {
    bottom: 10px;
    gap: 6px;
    padding: 8px;
  }

  .thumbnail {
    width: 40px;
    height: 40px;
  }
}
</style>